using UniversalAdmin.Application.DTOs;
using UniversalAdmin.Domain.Entities;
using UniversalAdmin.Domain.Repositories;
using UniversalAdmin.Shared.Enums;
using UniversalAdmin.Shared.Helpers;

namespace UniversalAdmin.Application.Services;

public class DocumentService : IDocumentService
{
    private readonly IDocumentRepository _documentRepository;
    private readonly IDocumentPermissionRepository _documentPermissionRepository;
    private readonly IUserRepository _userRepository;

    public DocumentService(
        IDocumentRepository documentRepository,
        IDocumentPermissionRepository documentPermissionRepository,
        IUserRepository userRepository)
    {
        _documentRepository = documentRepository;
        _documentPermissionRepository = documentPermissionRepository;
        _userRepository = userRepository;
    }

    public async Task<PagedResultDto<DocumentDto>> GetDocumentsAsync(int page = 1, int pageSize = 10, DocumentStatus? status = null, string? keyword = null)
    {
        var result = await _documentRepository.GetPagedAsync(page, pageSize, status, keyword);
        return new PagedResultDto<DocumentDto>
        {
            TotalCount = result.TotalCount,
            Items = result.Items.Select(MapToDto).ToList()
        };
    }

    public async Task<DocumentDto?> GetDocumentByIdAsync(Guid id)
    {
        var document = await _documentRepository.GetByIdAsync(id);
        return document != null ? MapToDto(document) : null;
    }

    public async Task<DocumentDto> CreateDocumentAsync(CreateDocumentDto dto, Guid userId)
    {
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
            throw new ArgumentException("用户不存在");

        var document = new Document
        {
            Title = dto.Title,
            Description = dto.Description,
            FilePath = dto.FilePath,
            FileSize = dto.FileSize,
            FileType = dto.FileType,
            Status = DocumentStatus.Draft,
            CreatedBy = userId,
            CreatedAt = DateTime.UtcNow,
            UpdatedAt = DateTime.UtcNow
        };

        await _documentRepository.AddAsync(document);
        return MapToDto(document);
    }

    public async Task<DocumentDto?> UpdateDocumentAsync(Guid id, UpdateDocumentDto dto)
    {
        var document = await _documentRepository.GetByIdAsync(id);
        if (document == null)
            return null;

        document.Title = dto.Title;
        document.Description = dto.Description;
        document.UpdatedAt = DateTime.UtcNow;

        await _documentRepository.UpdateAsync(document);
        return MapToDto(document);
    }

    public async Task<bool> DeleteDocumentAsync(Guid id)
    {
        var document = await _documentRepository.GetByIdAsync(id);
        if (document == null)
            return false;

        // 删除文档前先删除相关权限
        await _documentPermissionRepository.DeleteByDocumentIdAsync(id);
        await _documentRepository.DeleteAsync(document);
        return true;
    }

    public async Task<bool> UpdateDocumentStatusAsync(Guid id, DocumentStatus status)
    {
        var document = await _documentRepository.GetByIdAsync(id);
        if (document == null)
            return false;

        document.Status = status;
        document.UpdatedAt = DateTime.UtcNow;
        await _documentRepository.UpdateAsync(document);
        return true;
    }

    public async Task<IEnumerable<DocumentDto>> GetDocumentsByUserAsync(Guid userId, int page = 1, int pageSize = 10)
    {
        var documents = await _documentRepository.GetByUserIdAsync(userId, page, pageSize);
        return documents.Select(MapToDto);
    }

    public async Task<DocumentDto> UploadDocumentAsync(UploadDocumentDto dto, Guid userId)
    {
        // 检查文件路径是否已存在
        if (await _documentRepository.FilePathExistsAsync(dto.FilePath))
            throw new ArgumentException("文件路径已存在");

        var document = new Document
        {
            Title = dto.Title,
            Description = dto.Description,
            FilePath = dto.FilePath,
            FileSize = dto.FileSize,
            FileType = dto.FileType,
            Status = DocumentStatus.Draft,
            CreatedBy = userId,
            CreatedAt = DateTime.UtcNow,
            UpdatedAt = DateTime.UtcNow
        };

        await _documentRepository.AddAsync(document);
        return MapToDto(document);
    }

    public async Task<IEnumerable<DocumentDto>> GetRelatedDocumentsAsync(Guid documentId, int limit = 5)
    {
        var documents = await _documentRepository.GetRelatedDocumentsAsync(documentId, limit);
        return documents.Select(MapToDto);
    }

    private DocumentDto MapToDto(Document document)
    {
        return new DocumentDto
        {
            Id = document.Id,
            Title = document.Title,
            Description = document.Description,
            FilePath = document.FilePath,
            FileSize = document.FileSize,
            FileType = document.FileType,
            Status = document.Status,
            CreatedBy = document.CreatedBy,
            CreatedAt = document.CreatedAt,
            UpdatedAt = document.UpdatedAt
        };
    }
}